home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n16.arc / COMMON.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-27  |  5KB  |  143 lines

  1. UNIT common;
  2. {*******************************************************************************
  3. *                                                                              *
  4. *               PCMFAT 1.1/READBOOT 1.1  Common routines                       *
  5. *                     Copyright (c) 1991 Barry Simon                           *
  6. *                                                                              *
  7. *           First Published in PC Magazine, September 10, 1991                 *
  8. *                                                                              *
  9. *  Requires Turbo Pascal 6.0 to compile (because of use of inline assembler)   *
  10. *                                                                              *
  11. *******************************************************************************}
  12.   {$A-}
  13.  
  14. INTERFACE
  15. USES DOS;
  16.  
  17. TYPE
  18.   STR2 = STRING[2];
  19.   STR4 = STRING[4];
  20.   BootSectorType = RECORD
  21.                      unused : ARRAY[0..1] OF Byte;
  22.                      SystemID : STRING[8];
  23.                                    {we'll have to cheat to adjust the length
  24.                                    byte offset 2 is actually not used}
  25.                      BytesPerSector : Word; {offset 11,12}
  26.                      SectorsPerCluster : Byte; {offset 13}
  27.                      SectorsBeforeData : Word; {offset 14,15}
  28.                      NumFAT : Byte; {offset 16}
  29.                      NumRootDir,  {offset 17,18}
  30.                      NumSectors : Word; {offset 19,20}
  31.                      MediaDesc : Byte; {offset 21}
  32.                      NumSecPerFAT, {offset 22,23}
  33.                      NumSecPerTrack, {offset 24,25}
  34.                      NumHeads : Word; {offset 26,27}
  35.                      NumHidden,   {offset 28-31}
  36.                      LongNumSec : LongInt; {offset 32-35}
  37.                    END;
  38.  
  39. FUNCTION Hex(B : Byte) : STR2;
  40. FUNCTION HexWord(W : Word) : STR4;
  41. PROCEDURE ReadSector(SecNum : LongInt);
  42.  
  43. CONST
  44.   Use3NibbleFAT : Boolean = False;
  45.      {If there is a 3NibbleFAT, it is simplest to read in three sectors
  46.        of FAT at a time}
  47.  
  48. VAR
  49.  
  50.   PBlock : RECORD                 {needed for >32M disks under DOS 4/5}
  51.              SecNum : LongInt;
  52.              NumberToRead : Word;
  53.              BufferAddress : Pointer;
  54.            END;
  55.   Sector : ARRAY[0..8191] OF Byte; {512 needed in most cases; 8191
  56.                                             for safety in non-standard setups}
  57.   DriveNum : Byte;                {0=A;1=B; etc}
  58.   BootSector : BootSectorType ABSOLUTE Sector;
  59.  
  60.  
  61. IMPLEMENTATION
  62. CONST
  63.   HexDigits : ARRAY[0..15] OF Char = '0123456789ABCDEF';
  64.  
  65.   FUNCTION Hex(B : Byte) : STR2;  {Changes byte to hex string}
  66.   BEGIN
  67.     Hex := HexDigits[B DIV 16]+HexDigits[B MOD 16];
  68.   END;
  69.  
  70.   FUNCTION HexWord(W : Word) : STR4; {only used in PCMFAT}
  71.   BEGIN
  72.     HexWord := Hex(Hi(W))+Hex(Lo(W));
  73.   END;
  74.  
  75.   PROCEDURE ReadSector(SecNum : LongInt);
  76.   VAR
  77.     NeedPBlock, ErrorOccurred : Boolean;
  78.       {DOS 4.0 introduced an extended call to Int 25/26H; this was needed
  79.         for partitions over 32M.  It works with any drive so we always
  80.         use the extended call if DOS VER 4.0 or higher; this program will
  81.         not run as it stands with Compaq DOS 3.31 and larger than 32M
  82.         partitions}
  83.     BufferSeg, BufferOfs : Word;
  84.     FlagOut, ErrorOut, CXin, DXin : Word;
  85.   BEGIN
  86.     NeedPBlock := (Lo(DosVersion) > 3);
  87.     PBlock.SecNum := SecNum;
  88.     IF Use3NibbleFAT THEN PBlock.NumberToRead := 3 ELSE
  89.       PBlock.NumberToRead := 1;   {# sectors}
  90.     PBlock.BufferAddress := @Sector;
  91.     IF NeedPBlock THEN BEGIN
  92.       BufferSeg := Seg(PBlock);
  93.       BufferOfs := Ofs(PBlock);
  94.     END ELSE BEGIN
  95.       BufferSeg := Seg(Sector);
  96.       BufferOfs := Ofs(Sector);
  97.     END;
  98.     IF NeedPBlock THEN CXin := $FFFF ELSE
  99.       IF Use3NibbleFAT THEN CXin := 3 ELSE CXin := 1;
  100.     IF NeedPBlock THEN DXin := 0 ELSE DXin := Word(SecNum);
  101.     {Sec Num must be a word under DOS < 4}
  102.     asm
  103.     push ax
  104.     push bx
  105.     push cx
  106.     push dx
  107.     push bp
  108.     push si
  109.     push di
  110.     push es
  111.     push ds
  112.     mov al, DriveNum
  113.     mov ah, 0
  114.     mov cx, CXin
  115.     mov dx, DXin
  116.     mov ds, BufferSeg
  117.     mov bx, BufferOfs
  118.     Int 25H
  119.     pushf
  120.     pop bx
  121.     popf                          {restores original flags and stack}
  122.     pop ds
  123.     pop es
  124.     pop di
  125.     pop si
  126.     pop bp
  127.     pop dx
  128.     pop cx
  129.     mov FlagOut, bx
  130.     mov ErrorOut, ax
  131.     pop bx
  132.     pop ax
  133.   END;                            {inline assembler statements}
  134.   ErrorOccurred := (FlagOut AND FCarry <> 0);
  135.   IF ErrorOccurred THEN BEGIN
  136.       WriteLn('    Fatal Error reading sector; program halted.');
  137.       WriteLn('      Error Number ', HexWord(ErrorOut));
  138.       Halt;
  139.     END;
  140. END;
  141.  
  142. END.
  143.